/*************************************************************************
    > File Name    : Dictionary.cc
    > Author       : LiuLei
    > Mail         : 2261459486@qq.com 
    > Created Time : 2022年11月29日 星期三 09时15分05秒
 ************************************************************************/

#include "../../include/server/Dictionary.h"
#include <fstream>
#include <iostream>
#include <sstream>
using std::ifstream;
using std::cout;
using std::endl;
using std::istringstream;
using std::make_pair;

// 饿汉模式，线程安全
Dictionary *Dictionary::_pInstance = Dictionary::createInstance();
Dictionary::AutoRelease Dictionary::_ar;

Dictionary::AutoRelease::AutoRelease()
{

}

Dictionary::AutoRelease::~AutoRelease()
{
    if(nullptr == _pInstance)
    {
        delete _pInstance;
        _pInstance = nullptr;
    }
}

Dictionary* Dictionary::createInstance()
{
    if(nullptr == _pInstance)
    {
        _pInstance = new Dictionary();
    }
    return _pInstance;
}

void Dictionary::init()
{
    ifstream cnDictIfs(dict_cn);
    if(!cnDictIfs.good())
    {
        cout << "Open " << dict_cn << " error in Dictionary::init()!" << endl;
        return ;
    }

    ifstream enDictIfs(dict_en);
    if(!enDictIfs.good())
    {
        cout << "Open " << dict_en << " error in Dictionary::init()!" << endl;
        return ;
    }

    ifstream cnIndexIfs(index_cn);
    if(!cnIndexIfs.good())
    {
        cout << "Open " << index_cn << " error in Dictionary::init()!" << endl;
        return ;
    }

    ifstream enIndexIfs(index_en);
    if(!enIndexIfs.good())
    {
        cout << "Open " << index_en << " error in Dictionary::init()!" << endl;
        return ;
    }

    string line, word;
    int frenquency, index;

    // 插入中文词典
    cout << "Loading Chinese dictionary, please wait..." << endl;
    while(getline(cnDictIfs, line))
    {
        istringstream iss(line);
        iss >> word >> frenquency;
        _dict.push_back(make_pair(word, frenquency));
        line.clear();
    }
    // 英文词典的偏移量
    cout << "Chinese dictionary's size : " << _dict.size() << endl;

    // 插入英文词典
    size_t enDictOffset = _dict.size();
    cout << "Loading English dictionary, please wait..." << endl;
    while(getline(enDictIfs, line))
    {
        istringstream iss(line);
        iss >> word >> frenquency;
        _dict.push_back(make_pair(word, frenquency));
        line.clear();
    }
    cout << "English dictionary's size : " << _dict.size() - enDictOffset << endl;

    // 插入中文索引
    cout << "Loading Chinese index, please wait..." << endl;
    while(getline(cnIndexIfs, line))
    {
        istringstream iss(line);
        iss >> word;
        while(iss >> index)
        {
            _indexTable[word].insert(index);
        }
        line.clear();
    }

    // 插入英文索引
    cout << "Loading English index, please wait..." << endl;
    while(getline(enIndexIfs, line))
    {
        istringstream iss(line);
        iss >> word;
        while(iss >> index)
        {
            _indexTable[word].insert(enDictOffset + index);
        }
        line.clear();
    }

    // 关闭文件
    cnDictIfs.close();
    enDictIfs.close();
    cnIndexIfs.close();
    enIndexIfs.close();
}

vector<pair<string, int>> &Dictionary::getDictionary()
{
    return _dict;
}

map<string, set<int>> &Dictionary::getIndexTable()
{
    return _indexTable;
}

Dictionary::Dictionary()
{
    if(_pInstance)
    {
        this->init();
    }
}

Dictionary::~Dictionary()
{

}
